package com.jic.order.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jic.common.base.vo.RestResult;
import com.jic.common.redis.RedisClientTemplate;
import com.jic.common.utils.IDUtils;
import com.jic.common.utils.KeyUtils;
import com.jic.market.api.rest.CouponRestApi;
import com.jic.market.request.rest.coupon.SettlementMyCouponRequest;
import com.jic.market.request.rest.discount.PromotionGoods;
import com.jic.market.response.rest.coupon.QueryCouponPersonResponse;
import com.jic.order.rest.request.*;
import com.jic.order.rest.response.*;
import com.jic.product.after.api.ProductListApi;
import com.jic.product.after.response.ProductAfterInfoByIdResponse;
import com.jic.product.after.response.ShoppingCartResponse;
import com.jic.product.rest.response.ProductPropertyResponse;
import com.jic.order.constant.consist.ErrorInfo;
import com.jic.order.constant.consist.RedisKey;
import com.jic.order.entity.ShoppingCartEntity;
import com.jic.order.entity.ShoppingCartGoodsInfoEntity;
import com.jic.order.entity.ShoppingCartSubInfoEntity;
import com.jic.order.service.ShoppingCartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author: gaolanyu
 * @date: 2020-01-25
 * @remark: //TODO 分布式锁一期先不加 redis分布式锁已写好,单个用户购物车实体只允许同时存在一个变动操作
 */
@Service
@Slf4j
public class ShoppingCartServiceImpl implements ShoppingCartService {
    @Autowired
    RedisClientTemplate redisClientTemplate;
    @Resource
    ProductListApi productListApi;


    @Override
    public RestResult<ShoppingCartAddResponse> add(ShoppingCartAddRequest shoppingCartAddRequest, boolean directFlag) {
        if (checkShoppingCartEntityKeyExists(shoppingCartAddRequest.getUserId(), directFlag)) {
            saveCartInfoBySubInfo(shoppingCartAddRequest, directFlag);
            saveSubInfoByGoodsInfo(shoppingCartAddRequest, directFlag);
            saveGoodsInfo(shoppingCartAddRequest, directFlag);
            ShoppingCartAddResponse response = getShoppingCartAddResponse(shoppingCartAddRequest, directFlag);
            return RestResult.success(response);
        } else {
            ShoppingCartEntity shoppingCartEntity = setNewShoppingCartEntity(shoppingCartAddRequest);
            saveNewEntityToRedis(shoppingCartEntity, getShoppingCartEntityKey(shoppingCartAddRequest.getUserId(), directFlag));

            ShoppingCartSubInfoEntity shoppingCartSubInfoEntity = setNewShoppingCartSubInfoEntity(shoppingCartAddRequest);
            saveNewEntityToRedis(shoppingCartSubInfoEntity,
                    getShoppingCartSubInfoEntityKey(shoppingCartAddRequest.getUserId(),
                            shoppingCartSubInfoEntity.getShoppingCartChildrenId(), directFlag));

            ShoppingCartGoodsInfoEntity shoppingCartGoodsInfoEntity = setNewShoppingCartGoodsInfoEntity(shoppingCartAddRequest);
            saveNewEntityToRedis(shoppingCartGoodsInfoEntity,
                    getShoppingCartGoodsInfoEntityKey(shoppingCartAddRequest.getUserId(),
                            shoppingCartGoodsInfoEntity.getGoodsId(), directFlag));

            ShoppingCartAddResponse shoppingCartAddResponse = returnShoppingCartAddResponse(shoppingCartEntity);
            return RestResult.success(shoppingCartAddResponse);
        }
    }


    @Override
    public RestResult<ShoppingCartInfoListQueryResponse> queryShoppingCart(ShoppingCartInfoListQueryRequest request, boolean directFlag) {
        log.info("ShoppingCartServiceImpl==>queryShoppingCart==>,userId:{},directFlag:{}", request.getUserId(), directFlag);
        if (!checkShoppingCartEntityKeyExists(request.getUserId(), directFlag)) {
            return RestResult.success(new ShoppingCartInfoListQueryResponse());
        }
        String shoppingCartEntityKey = getShoppingCartEntityKey(request.getUserId(), directFlag);
        Map<String, String> result = redisClientTemplate.hgetAll(shoppingCartEntityKey);

        ShoppingCartInfoListQueryResponse response = new ShoppingCartInfoListQueryResponse();
        response.setBuyTotalAmount(new BigDecimal(result.get(RedisKey.buyTotalAmount)));
        response.setDiscountTotalAmount(new BigDecimal(result.get(RedisKey.discountTotalAmount)));
        response.setSaleTotalAmount(new BigDecimal(result.get(RedisKey.saleTotalAmount)));
        response.setShoppingCartId(result.get(RedisKey.shoppingCartId));

        String shoppingCartSubInfoListKey = result.get(RedisKey.shoppingCartSubInfoListKey);
        List<ShoppingCartSubInfo> shoppingCartSubInfos = getShoppingCartSubInfoList(shoppingCartSubInfoListKey, request.getUserId(), directFlag);
        log.info("ShoppingCartServiceImpl==>queryShoppingCart==>,userId:{},shoppingCartSubInfos:{}", request.getUserId(), shoppingCartSubInfos);
        response.setShoppingCartSubInfoList(shoppingCartSubInfos);
        return RestResult.success(response);
    }

    public ShoppingCartSubInfo getShoppingCartGoodsInfoList(List<String> goodsIdList, long userId, boolean directFlag, String childrenId) {
        ShoppingCartSubInfo shoppingCartSubInfo = new ShoppingCartSubInfo();
        shoppingCartSubInfo.setShoppingCartChildrenId(childrenId);

        String subKey = getShoppingCartSubInfoEntityKey(userId, childrenId, directFlag);
        Map<String, String> subEntity = redisClientTemplate.hgetAll(subKey);

        shoppingCartSubInfo.setMerchantId(Long.parseLong(subEntity.get(RedisKey.merchantId)));
        shoppingCartSubInfo.setMerchantName(subEntity.get(RedisKey.merchantName));
        shoppingCartSubInfo.setStoreId(Long.parseLong(subEntity.get(RedisKey.storeId)));
        shoppingCartSubInfo.setStoreName(subEntity.get(RedisKey.storeName));
        shoppingCartSubInfo.setStoreLogoUrl(subEntity.get(RedisKey.storeLogoUrl));

        List<ShoppingCartGoodsInfo> goodsInfoList = new ArrayList<>();
        BigDecimal subBuyTotalAmount = BigDecimal.ZERO;
        for (String goodsId : goodsIdList) {
            String goodsKey = getShoppingCartGoodsInfoEntityKey(userId, goodsId, directFlag);
            if (!redisClientTemplate.exists(goodsKey)) {
                continue;
            }
            Map<String, String> goodsInfo = redisClientTemplate.hgetAll(goodsKey);

            ShoppingCartGoodsInfo shoppingCartGoodsInfo = new ShoppingCartGoodsInfo();
            shoppingCartGoodsInfo.setSelected(getSelectedStatus(goodsInfo.get(RedisKey.selected)));
            shoppingCartGoodsInfo.setSaleUnitPrice(new BigDecimal(goodsInfo.get(RedisKey.saleUnitPrice)));
//            shoppingCartGoodsInfo.setGoodsUrl(goodsInfo.get(RedisKey.goodsUrl));
            shoppingCartGoodsInfo.setGoodsNum(Integer.parseInt(goodsInfo.get(RedisKey.goodsNum)));
//            shoppingCartGoodsInfo.setGoodsName(goodsInfo.get(RedisKey.goodsName));
            shoppingCartGoodsInfo.setGoodsId(goodsId);
            shoppingCartGoodsInfo.setDiscountUnitPrice(new BigDecimal(goodsInfo.get(RedisKey.discountUnitPrice)));
            shoppingCartGoodsInfo.setCouponId(new ArrayList<>());
            shoppingCartGoodsInfo.setCouponAmount(BigDecimal.ZERO);
            shoppingCartGoodsInfo.setBuyUnitPrice(new BigDecimal(goodsInfo.get(RedisKey.buyUnitPrice) == null ? "0" : goodsInfo.get(RedisKey.buyUnitPrice)));
            shoppingCartGoodsInfo.setThirdProductCode(goodsInfo.get(RedisKey.thirdProductCode));

            RestResult<ProductAfterInfoByIdResponse> responseRestResult = productListApi.queryProductInfoById(Long.valueOf(goodsId));
            if (null != responseRestResult && null != responseRestResult.getData()) {
                shoppingCartGoodsInfo.setGoodsName(responseRestResult.getData().getChineseName());
                shoppingCartGoodsInfo.setGoodsUrl(responseRestResult.getData().getPictureUrl());
            }

            ShoppingCartSubInfoEntity entity = getShoppingCartSubId(goodsId);
            shoppingCartSubInfo.setStoreLogoUrl(entity.getStoreLogoUrl());
            shoppingCartGoodsInfo.setProductPropertyValue(entity.getProductPropertyValue());

            goodsInfoList.add(shoppingCartGoodsInfo);
            if (shoppingCartGoodsInfo.getSelected()) {
                subBuyTotalAmount = subBuyTotalAmount.add(shoppingCartGoodsInfo.getBuyUnitPrice()
                        .multiply(new BigDecimal(shoppingCartGoodsInfo.getGoodsNum())));
            }
        }

        shoppingCartSubInfo.setSubBuyTotalAmount(subBuyTotalAmount);
        shoppingCartSubInfo.setShoppingCartGoodsInfoList(goodsInfoList);
        return shoppingCartSubInfo;
    }

    @Override
    public RestResult<Boolean> delete(ShoppingCartDeleteRequest request, boolean directFlag) {
        log.info("ShoppingCartServiceImpl==>delete==>,userId:{},directFlag:{}", request.getUserId(), directFlag);
        if (!checkShoppingCartEntityKeyExists(request.getUserId(), directFlag)) {
            return RestResult.error(ErrorInfo.SYSTEM_ERROR_CODE, "没有找到该用户购物车信息");
        }
        if (CollectionUtils.isEmpty(request.getShoppingCartDeleteSubRequests())) {
            return RestResult.error(ErrorInfo.SYSTEM_ERROR_CODE, "请选择要删除的商品!");
        }
        Boolean flag = deleteGoodsInfo(request, directFlag);

        //取出购物车所有选中商品 调用优惠券接口 选择最优优惠券 并更新购物车总价格
        ArrayList<ShoppingCartGoodsInfo> goodsInfos = new ArrayList<>();
        ShoppingCartInfoListQueryRequest queryRequest = new ShoppingCartInfoListQueryRequest();
        queryRequest.setUserId(request.getUserId());
        queryRequest.setToken(request.getToken());
        RestResult<ShoppingCartInfoListQueryResponse> cart = queryShoppingCart(queryRequest, directFlag);
        if (cart != null) {
            List<ShoppingCartSubInfo> shoppingCartSubInfoList = cart.getData().getShoppingCartSubInfoList();
            if (CollectionUtil.isNotEmpty(shoppingCartSubInfoList)) {
                for (ShoppingCartSubInfo shoppingCartSubInfo : shoppingCartSubInfoList) {
                    List<ShoppingCartGoodsInfo> infoList = shoppingCartSubInfo.getShoppingCartGoodsInfoList();
                    if (CollectionUtil.isNotEmpty(infoList)) {
                        for (ShoppingCartGoodsInfo shoppingCartGoodsInfo : infoList) {
                            Boolean selected = shoppingCartGoodsInfo.getSelected();
                            if (selected) {
                                goodsInfos.add(shoppingCartGoodsInfo);
                            }
                        }
                    }
                }
            }
        }
        BigDecimal total = BigDecimal.ZERO;
        if (goodsInfos.size() > 0) {
            SettlementMyCouponRequest couponRequest = new SettlementMyCouponRequest();
            List<PromotionGoods> settlementProductList = new ArrayList<PromotionGoods>();
            for (ShoppingCartGoodsInfo goodsInfo : goodsInfos) {
                total.add(goodsInfo.getSaleUnitPrice().multiply(new BigDecimal(goodsInfo.getGoodsNum())));
                PromotionGoods goods = new PromotionGoods();
                goods.setNum(Long.valueOf(goodsInfo.getGoodsNum()));
                goods.setLaunchFlag(0);
                goods.setThirdProductCode(goodsInfo.getThirdProductCode());
                settlementProductList.add(goods);
            }
            couponRequest.setSettlementProductList(settlementProductList);
            couponRequest.setToken("H5_LOGIN_TOKEN_" + request.getToken());
            RestResult<List<QueryCouponPersonResponse>> result = couponRestApi.settlementMyCouponList(couponRequest);
            if (result.getCode().equals("5000")) {
                return RestResult.success(flag);
            }
            //选择最优优惠券
            QueryCouponPersonResponse response = new QueryCouponPersonResponse();
            if (result != null && result.getCode().equals("0000")) {
                List<QueryCouponPersonResponse> data = result.getData();
                for (QueryCouponPersonResponse datum : data) {
                    BigDecimal limit = datum.getUseTotalAmountLimit();
                    if (total.compareTo(limit) > -1 && limit.compareTo(response.getUseTotalAmountLimit()) > -1) {
                        response = datum;
                    }
                }
            }
            BigDecimal subtract = BigDecimal.ZERO;
            if (response != null && response.getUseTotalAmountLimit().compareTo(BigDecimal.ZERO) == 1) {
                if (response.getCouponMode() == 1) {
                    subtract = subtract.multiply(response.getCouponAmount());
                } else if (response.getCouponMode() == 0) {
                    subtract = total.subtract(response.getCouponAmount());
                }
            }
            //更新购物车总价格
            if (subtract.compareTo(BigDecimal.ZERO) == 1) {
                String cartEntityKey = getShoppingCartEntityKey(request.getUserId(), directFlag);
                redisClientTemplate.hset(cartEntityKey, RedisKey.saleTotalAmount, subtract.toString());
                redisClientTemplate.hset(cartEntityKey, RedisKey.buyTotalAmount, subtract.toString());
                //优惠金额
                redisClientTemplate.hset(cartEntityKey, RedisKey.discountTotalAmount, total.subtract(subtract).toString());
            }
        }
        return RestResult.success(flag);
    }

    @Override
    public RestResult<Boolean> editNum(ShoppingCartEditRequest request, boolean directFlag) {
        log.info("ShoppingCartServiceImpl==>editNum==>,userId:{},req:{},directFlag:{}", request.getUserId(), request, directFlag);
        if (!checkShoppingCartEntityKeyExists(request.getUserId(), directFlag)) {
            return RestResult.error(ErrorInfo.SYSTEM_ERROR_CODE, "没有找到该用户购物车信息");
        }
        if (CollectionUtils.isEmpty(request.getShoppingCartGoodsNumInfos())) {
            return RestResult.error(ErrorInfo.SYSTEM_ERROR_CODE, "请传入要修改数量的商品");
        }
        Boolean flag = editGoodsNum(request, directFlag);
        return RestResult.success(flag);
    }

    /**
     * 选中购物车商品
     *
     * @param request
     * @param directFlag
     * @return
     */
    @Override
    public RestResult<Boolean> selected(ShoppingCartSelectedRequest request, boolean directFlag) {
        log.info("ShoppingCartServiceImpl==>selected==>,userId:{},req:{},directFlag:{}", request.getUserId(), request, directFlag);
        if (!checkShoppingCartEntityKeyExists(request.getUserId(), directFlag)) {
            return RestResult.error(ErrorInfo.SYSTEM_ERROR_CODE, "没有找到该用户购物车信息");
        }
        if (CollectionUtils.isEmpty(request.getGoodsIdList())) {
            return RestResult.error(ErrorInfo.SYSTEM_ERROR_CODE, "请选择选中的商品");
        }
        Boolean flag = selectedGoods(request, directFlag);
        return RestResult.success(flag);
    }

    @Override
    public RestResult<Boolean> unSelected(ShoppingCartSelectedRequest request, boolean directFlag) {
        if (!checkShoppingCartEntityKeyExists(request.getUserId(), directFlag)) {
            return RestResult.error(ErrorInfo.SYSTEM_ERROR_CODE, "没有找到该用户购物车信息");
        }
        if (CollectionUtils.isEmpty(request.getGoodsIdList())) {
            return RestResult.error(ErrorInfo.SYSTEM_ERROR_CODE, "请选择取消的商品");
        }
        Boolean flag = unSelectedGoods(request, directFlag);
        return RestResult.success(flag);
    }

    @Override
    public RestResult<Integer> queryShoppingCartNum(UserRequest request, boolean directFlag) {
        if (!checkShoppingCartEntityKeyExists(request.getUserId(), directFlag)) {
            return RestResult.success(0);
        }
        String cartKey = getShoppingCartEntityKey(request.getUserId(), directFlag);
        String shoppingCartSubInfoListKey = redisClientTemplate.hget(cartKey, RedisKey.shoppingCartSubInfoListKey);
        if (StringUtils.isEmpty(shoppingCartSubInfoListKey)) {
            return RestResult.success(0);
        }
        String[] subInfosList = shoppingCartSubInfoListKey.split("\\|");
        int cartNum = 0;
        for (String subInfoKey : subInfosList) {
            String subKey = getShoppingCartSubInfoEntityKey(request.getUserId(), subInfoKey, directFlag);
            String goodsIdKeyStr = redisClientTemplate.hget(subKey, RedisKey.shoppingCartGoodsInfoListKey);
            if (StringUtils.isEmpty(goodsIdKeyStr)) {
                continue;
            }
            String[] goodsIdKey = goodsIdKeyStr.split("\\|");
            for (String goodsId : goodsIdKey) {
                String goodsKey = getShoppingCartGoodsInfoEntityKey(request.getUserId(), goodsId, directFlag);
                if (!redisClientTemplate.exists(goodsKey)) {
                    continue;
                }
                String goodsNum = redisClientTemplate.hget(goodsKey, RedisKey.goodsNum);
                int goodsNumInt = Integer.parseInt(goodsNum);
                cartNum = cartNum + goodsNumInt;
            }
        }
        return RestResult.success(cartNum);
    }

    public boolean unSelectedGoods(ShoppingCartSelectedRequest request, boolean directFlag) {
        long userId = request.getUserId();
        for (String goodsId : request.getGoodsIdList()) {
            String goodsIdKey = getShoppingCartGoodsInfoEntityKey(userId, goodsId, directFlag);
            if (redisClientTemplate.exists(goodsIdKey)) {
                String selected = redisClientTemplate.hget(goodsIdKey, RedisKey.selected);
                if (getSelectedStatus(selected)) {
                    redisClientTemplate.hset(goodsIdKey, RedisKey.selected, "false");
                    setCartAmountByUnSelected(goodsIdKey, request.getUserId(), directFlag);
                }
            }
        }
        //取出购物车所有选中商品 调用优惠券接口 选择最优优惠券 并更新购物车总价格
        ArrayList<ShoppingCartGoodsInfo> goodsInfos = new ArrayList<>();
        ShoppingCartInfoListQueryRequest queryRequest = new ShoppingCartInfoListQueryRequest();
        queryRequest.setUserId(request.getUserId());
        queryRequest.setToken(request.getToken());
        RestResult<ShoppingCartInfoListQueryResponse> cart = queryShoppingCart(queryRequest, directFlag);
        if (cart != null) {
            List<ShoppingCartSubInfo> shoppingCartSubInfoList = cart.getData().getShoppingCartSubInfoList();
            if (CollectionUtil.isNotEmpty(shoppingCartSubInfoList)) {
                for (ShoppingCartSubInfo shoppingCartSubInfo : shoppingCartSubInfoList) {
                    List<ShoppingCartGoodsInfo> infoList = shoppingCartSubInfo.getShoppingCartGoodsInfoList();
                    if (CollectionUtil.isNotEmpty(infoList)) {
                        for (ShoppingCartGoodsInfo shoppingCartGoodsInfo : infoList) {
                            Boolean selected = shoppingCartGoodsInfo.getSelected();
                            if (selected) {
                                goodsInfos.add(shoppingCartGoodsInfo);
                            }
                        }
                    }
                }
            }
        }
        BigDecimal total = BigDecimal.ZERO;
        if (goodsInfos.size() > 0) {
            SettlementMyCouponRequest couponRequest = new SettlementMyCouponRequest();
            List<PromotionGoods> settlementProductList = new ArrayList<PromotionGoods>();
            for (ShoppingCartGoodsInfo goodsInfo : goodsInfos) {
                total.add(goodsInfo.getSaleUnitPrice().multiply(new BigDecimal(goodsInfo.getGoodsNum())));
                PromotionGoods goods = new PromotionGoods();
                goods.setNum(Long.valueOf(goodsInfo.getGoodsNum()));
                goods.setLaunchFlag(0);
                goods.setThirdProductCode(goodsInfo.getThirdProductCode());
                settlementProductList.add(goods);
            }
            couponRequest.setSettlementProductList(settlementProductList);
            couponRequest.setToken("H5_LOGIN_TOKEN_" + request.getToken());
            RestResult<List<QueryCouponPersonResponse>> result = couponRestApi.settlementMyCouponList(couponRequest);
            if (result.getCode().equals("5000")) {
                return true;
            }
            //选择最优优惠券
            QueryCouponPersonResponse response = new QueryCouponPersonResponse();
            if (result != null && result.getCode().equals("0000")) {
                List<QueryCouponPersonResponse> data = result.getData();
                for (QueryCouponPersonResponse datum : data) {
                    BigDecimal limit = datum.getUseTotalAmountLimit();
                    if (total.compareTo(limit) > -1 && limit.compareTo(response.getUseTotalAmountLimit()) > -1) {
                        response = datum;
                    }
                }
            }
            BigDecimal subtract = BigDecimal.ZERO;
            if (response != null && response.getUseTotalAmountLimit().compareTo(BigDecimal.ZERO) == 1) {
                if (response.getCouponMode() == 1) {
                    subtract = subtract.multiply(response.getCouponAmount());
                } else if (response.getCouponMode() == 0) {
                    subtract = total.subtract(response.getCouponAmount());
                }
            }
            //更新购物车总价格
            if (subtract.compareTo(BigDecimal.ZERO) == 1) {
                String cartEntityKey = getShoppingCartEntityKey(userId, directFlag);
                redisClientTemplate.hset(cartEntityKey, RedisKey.saleTotalAmount, subtract.toString());
                redisClientTemplate.hset(cartEntityKey, RedisKey.buyTotalAmount, subtract.toString());
                //优惠金额
                redisClientTemplate.hset(cartEntityKey, RedisKey.discountTotalAmount, total.subtract(subtract).toString());
            }
        }

        return true;
    }


    public boolean selectedGoods(ShoppingCartSelectedRequest request, boolean directFlag) {
        long userId = request.getUserId();
        for (String goodsId : request.getGoodsIdList()) {
            String goodsIdKey = getShoppingCartGoodsInfoEntityKey(userId, goodsId, directFlag);
            if (redisClientTemplate.exists(goodsIdKey)) {
                String selected = redisClientTemplate.hget(goodsIdKey, RedisKey.selected);
                if (!getSelectedStatus(selected)) {
                    redisClientTemplate.hset(goodsIdKey, RedisKey.selected, "true");
                    setCartAmountBySelected(goodsIdKey, request.getUserId(), directFlag);
                }
            }
        }
        //取出购物车所有选中商品 调用优惠券接口 选择最优优惠券 并更新购物车总价格
        ArrayList<ShoppingCartGoodsInfo> goodsInfos = new ArrayList<>();
        ShoppingCartInfoListQueryRequest queryRequest = new ShoppingCartInfoListQueryRequest();
        queryRequest.setUserId(request.getUserId());
        queryRequest.setToken(request.getToken());
        RestResult<ShoppingCartInfoListQueryResponse> cart = queryShoppingCart(queryRequest, directFlag);
        if (cart != null) {
            List<ShoppingCartSubInfo> shoppingCartSubInfoList = cart.getData().getShoppingCartSubInfoList();
            if (CollectionUtil.isNotEmpty(shoppingCartSubInfoList)) {
                for (ShoppingCartSubInfo shoppingCartSubInfo : shoppingCartSubInfoList) {
                    List<ShoppingCartGoodsInfo> infoList = shoppingCartSubInfo.getShoppingCartGoodsInfoList();
                    if (CollectionUtil.isNotEmpty(infoList)) {
                        for (ShoppingCartGoodsInfo shoppingCartGoodsInfo : infoList) {
                            Boolean selected = shoppingCartGoodsInfo.getSelected();
                            if (selected) {
                                goodsInfos.add(shoppingCartGoodsInfo);
                            }
                        }
                    }
                }
            }
        }
        BigDecimal total = BigDecimal.ZERO;
        if (goodsInfos.size() > 0) {
            SettlementMyCouponRequest couponRequest = new SettlementMyCouponRequest();
            List<PromotionGoods> settlementProductList = new ArrayList<PromotionGoods>();
            for (ShoppingCartGoodsInfo goodsInfo : goodsInfos) {
                total.add(goodsInfo.getSaleUnitPrice().multiply(new BigDecimal(goodsInfo.getGoodsNum())));
                PromotionGoods goods = new PromotionGoods();
                goods.setNum(Long.valueOf(goodsInfo.getGoodsNum()));
                goods.setLaunchFlag(0);
                goods.setThirdProductCode(goodsInfo.getThirdProductCode());
                settlementProductList.add(goods);
            }
            couponRequest.setSettlementProductList(settlementProductList);
            couponRequest.setToken(request.getToken());
            RestResult<List<QueryCouponPersonResponse>> result = couponRestApi.settlementMyCouponList(couponRequest);
            if (null != result && result.getCode().equals("5000")) {
                return true;
            }
            //选择最优优惠券
            QueryCouponPersonResponse response = new QueryCouponPersonResponse();
            if (result != null && result.getCode().equals("0000")) {
                List<QueryCouponPersonResponse> data = result.getData();
                for (QueryCouponPersonResponse datum : data) {
                    BigDecimal limit = datum.getUseTotalAmountLimit();
                    if (total.compareTo(limit) > -1 && limit.compareTo(response.getUseTotalAmountLimit()) > -1) {
                        response = datum;
                    }
                }
            }
            BigDecimal subtract = BigDecimal.ZERO;
            if (null != response && response.getUseTotalAmountLimit() != null && response.getUseTotalAmountLimit().compareTo(BigDecimal.ZERO) == 1) {
                if (response.getCouponMode() == 1) {
                    subtract = subtract.multiply(response.getCouponAmount());
                } else if (response.getCouponMode() == 0) {
                    subtract = total.subtract(response.getCouponAmount());
                }
            }
            //更新购物车总价格
            if (subtract.compareTo(BigDecimal.ZERO) == 1) {
                String cartEntityKey = getShoppingCartEntityKey(userId, directFlag);
                redisClientTemplate.hset(cartEntityKey, RedisKey.saleTotalAmount, subtract.toString());
                redisClientTemplate.hset(cartEntityKey, RedisKey.buyTotalAmount, subtract.toString());
                redisClientTemplate.hset(cartEntityKey, RedisKey.discountTotalAmount, total.subtract(subtract).toString());
            }
        }


        return true;
    }

    /**
     * 选中商品修改购物车总价
     *
     * @param goodsIdKey
     * @param userId
     * @param directFlag
     */
    public void setCartAmountBySelected(String goodsIdKey, long userId, boolean directFlag) {
        String goodsNum = redisClientTemplate.hget(goodsIdKey, RedisKey.goodsNum);
        String buyUnitPrice = redisClientTemplate.hget(goodsIdKey, RedisKey.buyUnitPrice);
        String cartEntityKey = getShoppingCartEntityKey(userId, directFlag);
        String saleTotalAmount = redisClientTemplate.hget(cartEntityKey, RedisKey.saleTotalAmount);
        String buyTotalAmount = redisClientTemplate.hget(cartEntityKey, RedisKey.buyTotalAmount);

        BigDecimal setAmount = new BigDecimal(buyUnitPrice).multiply(new BigDecimal(goodsNum));

        BigDecimal newSaleTotalAmount = new BigDecimal(saleTotalAmount).add(setAmount);
        BigDecimal newbuyTotalAmount = new BigDecimal(buyTotalAmount).add(setAmount);

        log.info("ShoppingCartServiceImpl==>setCartAmountBySelected==>,userId:{},goodsIdKey:{},buyTotalAmount:{},directFlag:{}", userId, goodsIdKey, buyTotalAmount, directFlag);
        log.info("ShoppingCartServiceImpl==>setCartAmountBySelected==>,userId:{},goodsIdKey:{},newbuyTotalAmount:{},directFlag:{}", userId, goodsIdKey, newbuyTotalAmount, directFlag);
        redisClientTemplate.hset(cartEntityKey, RedisKey.saleTotalAmount, newSaleTotalAmount.toString());
        redisClientTemplate.hset(cartEntityKey, RedisKey.buyTotalAmount, newbuyTotalAmount.toString());
    }

    public void setCartAmountByUnSelected(String goodsIdKey, long userId, boolean directFlag) {
        String goodsNum = redisClientTemplate.hget(goodsIdKey, RedisKey.goodsNum);
        String buyUnitPrice = redisClientTemplate.hget(goodsIdKey, RedisKey.buyUnitPrice);
        String cartEntityKey = getShoppingCartEntityKey(userId, directFlag);
        String saleTotalAmount = redisClientTemplate.hget(cartEntityKey, RedisKey.saleTotalAmount);
        String buyTotalAmount = redisClientTemplate.hget(cartEntityKey, RedisKey.buyTotalAmount);

        BigDecimal setAmount = new BigDecimal(buyUnitPrice).multiply(new BigDecimal(goodsNum));

        BigDecimal newSaleTotalAmount = new BigDecimal(saleTotalAmount).subtract(setAmount);
        BigDecimal newbuyTotalAmount = new BigDecimal(buyTotalAmount).subtract(setAmount);
        log.info("ShoppingCartServiceImpl==>setCartAmountByUnSelected==>,userId:{},goodsIdKey:{},buyTotalAmount:{},directFlag:{}", userId, goodsIdKey, buyTotalAmount, directFlag);
        log.info("ShoppingCartServiceImpl==>setCartAmountByUnSelected==>,userId:{},goodsIdKey:{},newbuyTotalAmount:{},directFlag:{}", userId, goodsIdKey, newbuyTotalAmount, directFlag);
        redisClientTemplate.hset(cartEntityKey, RedisKey.saleTotalAmount, newSaleTotalAmount.toString());
        redisClientTemplate.hset(cartEntityKey, RedisKey.buyTotalAmount, newbuyTotalAmount.toString());
    }

    public boolean editGoodsNum(ShoppingCartEditRequest request, boolean directFlag) {
        List<ShoppingCartGoodsNumInfo> shoppingCartGoodsNumInfos = request.getShoppingCartGoodsNumInfos();
        long userId = request.getUserId();
        for (ShoppingCartGoodsNumInfo shoppingCartGoodsNumInfo : shoppingCartGoodsNumInfos) {
            String goodsId = shoppingCartGoodsNumInfo.getGoodsId();
            String goodsIdKey = getShoppingCartGoodsInfoEntityKey(userId, goodsId, directFlag);
            if (redisClientTemplate.exists(goodsIdKey)) {
                String selected = redisClientTemplate.hget(goodsIdKey, RedisKey.selected);
                if (!getSelectedStatus(selected)) {
                    redisClientTemplate.hset(goodsIdKey, RedisKey.goodsNum, shoppingCartGoodsNumInfo.getGoodsNum().toString());
                } else {
                    setCartAmountByGoodsNum(goodsIdKey, userId, shoppingCartGoodsNumInfo.getGoodsNum(), directFlag);
                    redisClientTemplate.hset(goodsIdKey, RedisKey.goodsNum, shoppingCartGoodsNumInfo.getGoodsNum().toString());
                }
            }
        }
        return true;
    }

    public void setCartAmountByGoodsNum(String goodsIdKey, long userId, Integer goodsNums, boolean directFlag) {
        log.info("ShoppingCartServiceImpl==>setCartAmountByGoodsNum==>,userId:{},goodsIdKey:{},goodsNums:{},directFlag:{}", userId, goodsIdKey, goodsNums, directFlag);
        String goodsNum = redisClientTemplate.hget(goodsIdKey, RedisKey.goodsNum);
        String buyUnitPrice = redisClientTemplate.hget(goodsIdKey, RedisKey.buyUnitPrice);
        String cartEntityKey = getShoppingCartEntityKey(userId, directFlag);
        String saleTotalAmount = redisClientTemplate.hget(cartEntityKey, RedisKey.saleTotalAmount);
        String buyTotalAmount = redisClientTemplate.hget(cartEntityKey, RedisKey.buyTotalAmount);

        Integer goodsNumOld = Integer.parseInt(goodsNum);
        if (goodsNumOld > goodsNums) {
            BigDecimal setAmount = new BigDecimal(buyUnitPrice).multiply(new BigDecimal(goodsNumOld - goodsNums));

            BigDecimal newSaleTotalAmount = new BigDecimal(saleTotalAmount).subtract(setAmount);
            BigDecimal newbuyTotalAmount = new BigDecimal(buyTotalAmount).subtract(setAmount);

            log.info("ShoppingCartServiceImpl==>setCartAmountByGoodsNum==>,userId:{},goodsIdKey:{},goodsNumOld:{},saleTotalAmount:{},buyTotalAmount:{},directFlag:{}", userId, goodsIdKey, goodsNumOld, saleTotalAmount, buyTotalAmount, directFlag);
            log.info("ShoppingCartServiceImpl==>setCartAmountByGoodsNum==>,userId:{},goodsIdKey:{},goodsNums:{},newSaleTotalAmount:{},newbuyTotalAmount:{},directFlag:{}", userId, goodsIdKey, goodsNums, newSaleTotalAmount, newbuyTotalAmount, directFlag);
            redisClientTemplate.hset(cartEntityKey, RedisKey.saleTotalAmount, newSaleTotalAmount.toString());
            redisClientTemplate.hset(cartEntityKey, RedisKey.buyTotalAmount, newbuyTotalAmount.toString());
        } else if (goodsNumOld < goodsNums) {
            BigDecimal setAmount = new BigDecimal(buyUnitPrice).multiply(new BigDecimal(goodsNums - goodsNumOld));

            BigDecimal newSaleTotalAmount = new BigDecimal(saleTotalAmount).add(setAmount);
            BigDecimal newbuyTotalAmount = new BigDecimal(buyTotalAmount).add(setAmount);

            log.info("ShoppingCartServiceImpl==>setCartAmountByGoodsNum==>,userId:{},goodsIdKey:{},goodsNumOld:{},saleTotalAmount:{},buyTotalAmount:{},directFlag:{}", userId, goodsIdKey, goodsNumOld, saleTotalAmount, buyTotalAmount, directFlag);
            log.info("ShoppingCartServiceImpl==>setCartAmountByGoodsNum==>,userId:{},goodsIdKey:{},goodsNums:{},newSaleTotalAmount:{},newbuyTotalAmount:{},directFlag:{}", userId, goodsIdKey, goodsNums, newSaleTotalAmount, newbuyTotalAmount, directFlag);
            redisClientTemplate.hset(cartEntityKey, RedisKey.saleTotalAmount, newSaleTotalAmount.toString());
            redisClientTemplate.hset(cartEntityKey, RedisKey.buyTotalAmount, newbuyTotalAmount.toString());
        }
    }

    @Override
    public Boolean deleteGoodsInfo(ShoppingCartDeleteRequest request, boolean directFlag) {
        List<ShoppingCartDeleteSubRequest> selectCartsList = request.getShoppingCartDeleteSubRequests();
        for (ShoppingCartDeleteSubRequest shoppingCartDeleteSubRequest : selectCartsList) {
            deleteSubInfoGoodsIdInfo(request.getUserId(),
                    shoppingCartDeleteSubRequest.getShoppingCardChildrenId(),
                    shoppingCartDeleteSubRequest.getGoodsIdList(), directFlag);

            deleteGoodsInfoByRequestGoodsList(request.getUserId(), shoppingCartDeleteSubRequest, directFlag);
        }
        return true;
    }

    public void deleteGoodsInfoByRequestGoodsList(long userId, ShoppingCartDeleteSubRequest shoppingCartDeleteSubRequest, boolean directFlag) {
        if (CollectionUtils.isEmpty(shoppingCartDeleteSubRequest.getGoodsIdList())) {
            return;
        }
        shoppingCartDeleteSubRequest.getGoodsIdList().stream().forEach(goodsId -> {
            String goodsIdKey = getShoppingCartGoodsInfoEntityKey(userId, goodsId, directFlag);
            if (redisClientTemplate.exists(goodsIdKey)) {
                String selected = redisClientTemplate.hget(goodsIdKey, RedisKey.selected);
                if (!getSelectedStatus(selected)) {
                    redisClientTemplate.del(goodsIdKey);
                } else {
                    setCartAmount(goodsIdKey, userId, directFlag);
                    redisClientTemplate.del(goodsIdKey);
                }
            }
        });
    }

    public void setCartAmount(String goodsIdKey, long userId, boolean directFlag) {
        String goodsNum = redisClientTemplate.hget(goodsIdKey, RedisKey.goodsNum);
        String buyUnitPrice = redisClientTemplate.hget(goodsIdKey, RedisKey.buyUnitPrice);
        BigDecimal removeAmount = new BigDecimal(buyUnitPrice).multiply(new BigDecimal(goodsNum));

        String cartEntityKey = getShoppingCartEntityKey(userId, directFlag);
        String saleTotalAmount = redisClientTemplate.hget(cartEntityKey, RedisKey.saleTotalAmount);
        String buyTotalAmount = redisClientTemplate.hget(cartEntityKey, RedisKey.buyTotalAmount);

        BigDecimal newSaleTotalAmount = new BigDecimal(saleTotalAmount).subtract(removeAmount);
        BigDecimal newbuyTotalAmount = new BigDecimal(buyTotalAmount).subtract(removeAmount);
        redisClientTemplate.hset(cartEntityKey, RedisKey.saleTotalAmount, newSaleTotalAmount.toString());
        redisClientTemplate.hset(cartEntityKey, RedisKey.buyTotalAmount, newbuyTotalAmount.toString());
    }

    public void deleteSubInfoGoodsIdInfo(long userId, String shoppingCardChildrenId, List<String> goodsIdList, boolean directFlag) {
        log.info("ShoppingCartServiceImpl==>deleteSubInfoGoodsIdInfo==>,userId:{},directFlag:{}", userId, directFlag);
        String subInfoEntityKey = getShoppingCartSubInfoEntityKey(userId, shoppingCardChildrenId, directFlag);
        String goodsIdListStr = redisClientTemplate.hget(subInfoEntityKey, RedisKey.shoppingCartGoodsInfoListKey);
        if (StringUtils.isEmpty(goodsIdListStr)) {
            return;
        }
        String[] goodsIds = goodsIdListStr.split("\\|");
        List<String> goodsIdResultList = Stream.of(goodsIds).collect(Collectors.toList());
        goodsIdResultList.removeAll(goodsIdList);
//        String resultStr = goodsIdResultList.stream().reduce("|", String::concat);
        String resultStr = getGoodsIdListStr(goodsIdResultList);
        log.info("ShoppingCartServiceImpl==>deleteSubInfoGoodsIdInfo==>,userId:{},directFlag:{},resultStr:{}", userId, directFlag, resultStr);
        redisClientTemplate.hset(subInfoEntityKey, RedisKey.shoppingCartGoodsInfoListKey, resultStr);
    }

    public String getGoodsIdListStr(List<String> goodsIdResultList) {
        String resultStr = "";
        if (CollectionUtils.isEmpty(goodsIdResultList)) {
            return resultStr;
        }
        for (String goodsId : goodsIdResultList) {
            if (StringUtils.isEmpty(resultStr)) {
                resultStr = goodsId;
            } else {
                resultStr = resultStr + "|" + goodsId;
            }
        }
        return resultStr;
    }

    public List<ShoppingCartSubInfo> getShoppingCartSubInfoList(String shoppingCartSubInfoListKey, long userId, boolean directFlag) {
        if (StringUtils.isEmpty(shoppingCartSubInfoListKey)) {
            return new ArrayList<ShoppingCartSubInfo>();
        }
        List<ShoppingCartSubInfo> subInfosList = new ArrayList<>();
        String[] subInfos = shoppingCartSubInfoListKey.split("\\|");
        for (String subInfo : subInfos) {
            String subInfoKey = getShoppingCartSubInfoEntityKey(userId, subInfo, directFlag);
            String shoppingCartSubInfoList = redisClientTemplate.hget(subInfoKey, RedisKey.shoppingCartGoodsInfoListKey);

            String[] goodsIdArray = shoppingCartSubInfoList.split("\\|");
            List<String> goodsIdList = Stream.of(goodsIdArray).collect(Collectors.toList());
            ShoppingCartSubInfo shoppingCartSubInfo = getShoppingCartGoodsInfoList(goodsIdList, userId, directFlag, subInfo);

            log.info("ShoppingCartServiceImpl==>queryShoppingCart==>,userId:{},shoppingCartSubInfo:{}", userId, shoppingCartSubInfo);
            if (!CollectionUtils.isEmpty(shoppingCartSubInfo.getShoppingCartGoodsInfoList())) {
                subInfosList.add(shoppingCartSubInfo);
            }
        }
        return subInfosList;
    }


    public Boolean getSelectedStatus(String selected) {
        if ("true".equals(selected) || "TRUE".equals(selected)) {
            return true;
        }
        return false;
    }

    public ShoppingCartAddResponse getShoppingCartAddResponse(ShoppingCartAddRequest shoppingCartAddRequest, boolean directFlag) {
        ShoppingCartAddResponse shoppingCartAddResponse = new ShoppingCartAddResponse();
        shoppingCartAddResponse.setShoppingCardChildrenId(getShoppingCartSubId(shoppingCartAddRequest.getGoodsId()).getShoppingCartChildrenId());

        String cartKey = getShoppingCartEntityKey(shoppingCartAddRequest.getUserId(), directFlag);

        String cardId = redisClientTemplate.hget(cartKey, RedisKey.shoppingCartId);
        String saleTotalAmount = redisClientTemplate.hget(cartKey, RedisKey.saleTotalAmount);

        shoppingCartAddResponse.setShoppingCardId(cardId);
        shoppingCartAddResponse.setSaleTotalAmount(new BigDecimal(saleTotalAmount));
        return shoppingCartAddResponse;
    }


    public void saveGoodsInfo(ShoppingCartAddRequest shoppingCartAddRequest, boolean directFlag) {
        String goodsInfoKey = getShoppingCartGoodsInfoEntityKey(shoppingCartAddRequest.getUserId(),
                shoppingCartAddRequest.getGoodsId(), directFlag);
        if (redisClientTemplate.exists(goodsInfoKey)) {
            redisClientTemplate.hincrBy(goodsInfoKey, RedisKey.goodsNum, Long.valueOf(shoppingCartAddRequest.getGoodsNum()));
        } else {
            ShoppingCartGoodsInfoEntity shoppingCartGoodsInfoEntity = setNewShoppingCartGoodsInfoEntity(shoppingCartAddRequest);
            saveNewEntityToRedis(shoppingCartGoodsInfoEntity,
                    getShoppingCartGoodsInfoEntityKey(shoppingCartAddRequest.getUserId(),
                            shoppingCartGoodsInfoEntity.getGoodsId(), directFlag));
        }
    }

    public void saveCartInfoBySubInfo(ShoppingCartAddRequest shoppingCartAddRequest, boolean directFlag) {
        String cartEntity = getShoppingCartEntityKey(shoppingCartAddRequest.getUserId(), directFlag);
        String subInfoId = getShoppingCartSubId(shoppingCartAddRequest.getGoodsId()).getShoppingCartChildrenId();

        String results = redisClientTemplate.hget(cartEntity, RedisKey.shoppingCartSubInfoListKey);
        if (StringUtils.isEmpty(results)) {
            redisClientTemplate.hset(cartEntity, RedisKey.shoppingCartSubInfoListKey, subInfoId);
        } else if (!results.contains(subInfoId)) {
            if (!results.endsWith("|")) {
                results = results + "|";
            }
            results = results + subInfoId;
            redisClientTemplate.hset(cartEntity, RedisKey.shoppingCartSubInfoListKey, results);
        }
    }

    public void saveSubInfoByGoodsInfo(ShoppingCartAddRequest shoppingCartAddRequest, boolean directFlag) {
        if (checkShoppingCartSubInfoEntityKeyExists(shoppingCartAddRequest.getUserId(), shoppingCartAddRequest.getGoodsId(), directFlag)) {
            saveSubInfoGoodsInfo(shoppingCartAddRequest.getUserId(), shoppingCartAddRequest.getGoodsId(), directFlag);
        } else {
            ShoppingCartSubInfoEntity shoppingCartSubInfoEntity = setNewShoppingCartSubInfoEntity(shoppingCartAddRequest);
            saveNewEntityToRedis(shoppingCartSubInfoEntity,
                    getShoppingCartSubInfoEntityKey(shoppingCartAddRequest.getUserId(),
                            shoppingCartSubInfoEntity.getShoppingCartChildrenId(), directFlag));
        }
    }

    public Boolean checkShoppingCartEntityKeyExists(long userId, boolean directFlag) {
        String shoppingCartEntityKey = getShoppingCartEntityKey(userId, directFlag);
        return redisClientTemplate.exists(shoppingCartEntityKey);
    }

    public Boolean checkShoppingCartSubInfoEntityKeyExists(long userId, String gooodsId, boolean directFlag) {
        String subInfoEntityKey = getShoppingCartSubInfoEntityKey(userId, getShoppingCartSubId(gooodsId).getShoppingCartChildrenId(), directFlag);
        return redisClientTemplate.exists(subInfoEntityKey);
    }

    public void saveSubInfoGoodsInfo(long userId, String goodsId, boolean directFlag) {
        String subInfoEntityKey = getShoppingCartSubInfoEntityKey(userId, getShoppingCartSubId(goodsId).getShoppingCartChildrenId(), directFlag);
        String results = redisClientTemplate.hget(subInfoEntityKey, RedisKey.shoppingCartGoodsInfoListKey);
        if (StringUtils.isEmpty(results)) {
            redisClientTemplate.hset(subInfoEntityKey, RedisKey.shoppingCartGoodsInfoListKey, goodsId);
        } else if (!results.contains(goodsId)) {
            if (!results.endsWith("|")) {
                results = results + "|";
            }
            results = results + goodsId;
            redisClientTemplate.hset(subInfoEntityKey, RedisKey.shoppingCartGoodsInfoListKey, results);
        }
    }

    public String getShoppingCartEntityKey(long userId, boolean directFlag) {
        String key = "";
        if (directFlag) {
            key = RedisKey.ShoppingDirectCartEntityKey;
        } else {
            key = RedisKey.ShoppingCartEntityKey;
        }
        HashMap<String, String> param = new HashMap<>(2);
        param.put(RedisKey.userId, Long.toString(userId));
        String shoppingCartEntityKey = KeyUtils.replaceKey(key, param);
        return shoppingCartEntityKey;
    }

    public String getShoppingCartGoodsInfoEntityKey(long userId, String shoppingCartGoodsInfoEntityKey, boolean directFlag) {
        String key = "";
        if (directFlag) {
            key = RedisKey.ShoppingDirectCartGoodsInfoEntityKey;
        } else {
            key = RedisKey.ShoppingCartGoodsInfoEntityKey;
        }
        HashMap<String, String> param = new HashMap<>(2);
        param.put(RedisKey.userId, Long.toString(userId));
        param.put(RedisKey.shoppingCartGoodsInfoListKey, shoppingCartGoodsInfoEntityKey);
        String shoppingCartGoodsInfoEntity = KeyUtils.replaceKey(key, param);
        return shoppingCartGoodsInfoEntity;
    }

    public String getShoppingCartSubInfoEntityKey(long userId, String shoppingCartSubInfoListKey, boolean directFlag) {
        String key = "";
        if (directFlag) {
            key = RedisKey.ShoppingDirectCartSubInfoEntityKey;
        } else {
            key = RedisKey.ShoppingCartSubInfoEntityKey;
        }
        HashMap<String, String> param = new HashMap<>(2);
        param.put(RedisKey.userId, Long.toString(userId));
        param.put(RedisKey.shoppingCartSubInfoListKey, shoppingCartSubInfoListKey);
        String shoppingCartSubInfoList = KeyUtils.replaceKey(key, param);
        return shoppingCartSubInfoList;
    }

    public ShoppingCartEntity setNewShoppingCartEntity(ShoppingCartAddRequest shoppingCartAddRequest) {
        ShoppingCartEntity shoppingCartEntity = new ShoppingCartEntity();
        String shoppingCartId = IDUtils.GenerateBillNo("8077");
        shoppingCartEntity.setShoppingCartId(shoppingCartId);
        shoppingCartEntity.setBuyTotalAmount(BigDecimal.ZERO.toString());
        shoppingCartEntity.setDiscountTotalAmount(BigDecimal.ZERO.toString());
        shoppingCartEntity.setSaleTotalAmount(BigDecimal.ZERO.toString());
        shoppingCartEntity.setShoppingCartSubInfoListKey(getShoppingCartSubId(shoppingCartAddRequest.getGoodsId()).getShoppingCartChildrenId());
        return shoppingCartEntity;
    }

    public ShoppingCartSubInfoEntity setNewShoppingCartSubInfoEntity(ShoppingCartAddRequest shoppingCartAddRequest) {
        ShoppingCartSubInfoEntity shoppingCartSubInfoEntity = getShoppingCartSubId(shoppingCartAddRequest.getGoodsId());
        shoppingCartSubInfoEntity.setShoppingCartGoodsInfoListKey(shoppingCartAddRequest.getGoodsId());
        return shoppingCartSubInfoEntity;
    }

    @Resource
    private CouponRestApi couponRestApi;

    public ShoppingCartGoodsInfoEntity setNewShoppingCartGoodsInfoEntity(ShoppingCartAddRequest shoppingCartAddRequest) {
        ShoppingCartGoodsInfoEntity shoppingCartGoodsInfoEntity = new ShoppingCartGoodsInfoEntity();
        RestResult<ProductAfterInfoByIdResponse> responseRestResult = productListApi.queryProductInfoById(Long.valueOf(shoppingCartAddRequest.getGoodsId()));
        if (responseRestResult.getData() != null) {
            shoppingCartGoodsInfoEntity.setGoodsName(responseRestResult.getData().getChineseName());
            shoppingCartGoodsInfoEntity.setGoodsUrl(responseRestResult.getData().getPictureUrl());
            shoppingCartGoodsInfoEntity.setThirdProductCode(responseRestResult.getData().getCode());
        }
        shoppingCartGoodsInfoEntity.setBuyUnitPrice(shoppingCartAddRequest.getSaleUnitPrice().toString());
        shoppingCartGoodsInfoEntity.setSaleUnitPrice(shoppingCartAddRequest.getSaleUnitPrice().toString());
        shoppingCartGoodsInfoEntity.setCouponAmount(BigDecimal.ZERO.toString());
        shoppingCartGoodsInfoEntity.setCouponId(new ArrayList<>());
        shoppingCartGoodsInfoEntity.setDiscountUnitPrice(BigDecimal.ZERO.toString());
        shoppingCartGoodsInfoEntity.setGoodsId(shoppingCartAddRequest.getGoodsId());
        shoppingCartGoodsInfoEntity.setGoodsName(shoppingCartAddRequest.getGoodsName());
        shoppingCartGoodsInfoEntity.setGoodsNum(Integer.toString(shoppingCartAddRequest.getGoodsNum() == null ? 1 : shoppingCartAddRequest.getGoodsNum()));
        shoppingCartGoodsInfoEntity.setGoodsUrl(shoppingCartAddRequest.getGoodsUrl());
        shoppingCartGoodsInfoEntity.setSelected("false");
        shoppingCartGoodsInfoEntity.setPromotionId(shoppingCartAddRequest.getPromotionId());
        shoppingCartGoodsInfoEntity.setPromotionType(shoppingCartAddRequest.getPromotionType());
        shoppingCartGoodsInfoEntity.setGroupType(shoppingCartAddRequest.getGroupType());
        return shoppingCartGoodsInfoEntity;
    }

    public void saveNewEntityToRedis(Object entity, String redisKey) {
        String entityStr = JSON.toJSONString(entity);
        JSONObject entityJSONObject = JSON.parseObject(entityStr);
        Map<String, Object> entityMap = entityJSONObject.getInnerMap();

        Map<String, String> strMap = new HashMap<>();
        entityMap.entrySet().forEach(entry ->
                strMap.put(entry.getKey(), entry.getValue().toString()));
        redisClientTemplate.hmset(redisKey, strMap);
    }

    public ShoppingCartAddResponse returnShoppingCartAddResponse(ShoppingCartEntity shoppingCartEntity) {
        ShoppingCartAddResponse shoppingCartAddResponse = new ShoppingCartAddResponse();
        shoppingCartAddResponse.setSaleTotalAmount(new BigDecimal(shoppingCartEntity.getSaleTotalAmount()));
        shoppingCartAddResponse.setShoppingCardId(shoppingCartEntity.getShoppingCartId());
        shoppingCartAddResponse.setShoppingCardChildrenId(shoppingCartEntity.getShoppingCartSubInfoListKey());
        return shoppingCartAddResponse;
    }

    public ShoppingCartSubInfoEntity getShoppingCartSubId(String goodsId) {
        //TODO 通过skuId需要调用接口查询商家Id 这里返回
        ShoppingCartSubInfoEntity subInfoEntity = new ShoppingCartSubInfoEntity();
        subInfoEntity.setShoppingCartChildrenId("0");
        subInfoEntity.setMerchantId("0");
        subInfoEntity.setMerchantName("默认商家");
        subInfoEntity.setStoreId("0");
        subInfoEntity.setStoreLogoUrl("");
        subInfoEntity.setStoreName("默认店铺");

        try {
            log.info("productListApi.getSkuByProdId==>goodsId:{},data:{}", goodsId);
            RestResult<ShoppingCartResponse> response = productListApi.getSkuByProdId(Long.parseLong(goodsId));
            log.info("productListApi.getSkuByProdId==>resp:{},data:{}", response, response.getData());
            if (!RestResult.checkIsSuccess(response) || response.getData() == null) {
                return subInfoEntity;
            }
            ShoppingCartResponse shoppingCartResponse = response.getData();
            subInfoEntity.setShoppingCartChildrenId(Long.toString(shoppingCartResponse.getStoreId()));
            subInfoEntity.setStoreLogoUrl(shoppingCartResponse.getStoreLogoUrl());
            subInfoEntity.setStoreName(shoppingCartResponse.getStoreName());
            subInfoEntity.setStoreId(Long.toString(shoppingCartResponse.getStoreId()));
            subInfoEntity.setMerchantName(shoppingCartResponse.getMerchantName());
            subInfoEntity.setMerchantId(Long.toString(shoppingCartResponse.getDeptId()));
            subInfoEntity.setProductPropertyValue(getProductPropertyEntitys(shoppingCartResponse.getProductPropertyValue()));
            subInfoEntity.setDeptId(shoppingCartResponse.getDeptId());
        } catch (Exception e) {
            log.error("productListApi.getSkuByProdId==>error", e);
        }
        return subInfoEntity;
    }

    public List<ProductPropertyEntity> getProductPropertyEntitys(List<ProductPropertyResponse> responseList) {
        if (CollectionUtils.isEmpty(responseList)) {
            return new ArrayList<>();
        }
        List<ProductPropertyEntity> entityList = new ArrayList<>();
        for (ProductPropertyResponse response : responseList) {
            ProductPropertyEntity entity = new ProductPropertyEntity();
            entity.setAttrId(response.getAttrId());
            entity.setAttrName(response.getAttrName());
            entity.setValueId(response.getValueId());
            entity.setValueName(response.getValueName());
            entityList.add(entity);
        }
        return entityList;
    }

    @Override
    public String getUserIdByToken(String token) {
        //TODO 先放在这里 token 解析后期放网关
        // 获取用户id
        String userStr = redisClientTemplate.get("H5_LOGIN_TOKEN_" + token);
        if (org.apache.commons.lang.StringUtils.isEmpty(userStr)) {
            return "";
        }
        Map<String, Object> userMap = JSONArray.parseObject(userStr, HashMap.class);
        String userId = userMap.get("id").toString();
        return userId;
    }
}
